package com.wyb.fastdfs.service.impl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.wyb.fastdfs.config.ElasticSearchConfig;
import com.wyb.fastdfs.constant.EsConstant;
import com.wyb.fastdfs.dto.es.FileEsModel;
import com.wyb.fastdfs.service.FileSearchService;
import com.wyb.fastdfs.vo.SearchParam;
import com.wyb.fastdfs.vo.SearchResult;

/**
 * @Author:wangyibo
 * @Date 2021年8月12日
 * @Version:1.0
 * @Description:TODO
 */
@Service
public class FileSearchServiceImpl implements FileSearchService {

	@Autowired
	private RestHighLevelClient client;

	/**
	 * 通过检索参数得到检索结果
	 */
	@Override
	public SearchResult search(SearchParam searchParam) {
		// 动态构建查询需要的DSL语句

		SearchResult result = null;
		// 准备检索请求
		SearchRequest searchRequest = buildSearchRequest(searchParam);

		try {
			// 执行检索请求
			SearchResponse response = client.search(searchRequest, ElasticSearchConfig.COMMON_OPTION);

			System.out.println(response);

			result = buildSearchResult(response);
			// 分析响应数据并封装成指定格式
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;
	}

	/**
	 * 构建检索结果
	 * 
	 * @param response
	 * @return
	 */
	private SearchResult buildSearchResult(SearchResponse response) {
		SearchResult searchResult = new SearchResult();

		SearchHits hits = response.getHits();

		SearchHit[] searchHits = hits.getHits();

		List<FileEsModel> esModels = new ArrayList<>();

		if (searchHits != null && searchHits.length > 0) {
			for (SearchHit hit : searchHits) {
				String sourceAsString = hit.getSourceAsString();
//				FileEsModel file = new FileEsModel();
				FileEsModel esModel = JSON.parseObject(sourceAsString, FileEsModel.class);
				esModels.add(esModel);
			}
			searchResult.setFileEsModels(esModels);
		}

		searchResult.setPageNum(5);

		long total = hits.getTotalHits().value;
		searchResult.setTotal(hits.getTotalHits().value);

		int totalPages = (int) total == 0 ? (int) total / 5 : (int) total / 5 + 1;
		// 总页码自己计算
		searchResult.setTotalPages(totalPages);

		return searchResult;
	}

	/**
	 * 构造检索请求 #模糊匹配，过滤（属性（nested），分类，区间），排序，分页，高亮，聚合分析
	 * 
	 * @param searchParam
	 * @return
	 */
	private SearchRequest buildSearchRequest(SearchParam searchParam) {
		SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
		/**
		 * 模糊匹配，过滤（属性（nested），分类，区间）
		 */
		// 构建bool-query
		BoolQueryBuilder boolquery = QueryBuilders.boolQuery();
		// must模糊匹配
		if (StringUtils.isNotEmpty(searchParam.getKeyword())) {
			boolquery.must(QueryBuilders.matchQuery("fileTitle", searchParam.getKeyword()));
		}
		if (StringUtils.isNotEmpty(searchParam.getAuthor())) {
			boolquery.must(QueryBuilders.matchQuery("author", searchParam.getAuthor()));
		}
		// filter过滤
		if (searchParam.getCategoryId() != null) {
			boolquery.filter(QueryBuilders.termQuery("categoryId", searchParam.getCategoryId()));
		}

		// TODO 按照扩展名查询（后期）
//		if(searchParam.getExtId() != null && searchParam.getExtId().size() >0) {
//			boolquery.filter(QueryBuilders.termQuery("extId", searchParam.getExtId()));
//		}

		// 按照状态查询（后期）
//		boolquery.filter(QueryBuilders.termQuery("status", searchParam.getStatus() == 1));

		// 下载量区间查询（后期）
//		if (StringUtils.isNotEmpty(searchParam.getDownCount())) {
//			RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("downCount");
//			String[] strings = searchParam.getDownCount().split("_");
//			if (strings.length == 2) {
//				rangeQuery.gte(strings[0]).lte(strings[1]);
//			} else if (strings.length == 1) {
//				if (searchParam.getDownCount().startsWith("_")) {
//					rangeQuery.lte(strings[0]);
//				}
//				if (searchParam.getDownCount().endsWith("_")) {
//					rangeQuery.gte(strings[0]);
//				}
//
//			}
//			boolquery.filter(rangeQuery);
//		}
		sourceBuilder.query(boolquery);

		/**
		 * 排序，分页，高亮
		 */
//		if(StringUtils.isNoneEmpty(searchParam.getSort())) {
//			String sort = searchParam.getSort();
//			
//			String[] strings = sort.split("_");
//			
//			SortOrder order = strings[1].equalsIgnoreCase("asc") ? SortOrder.ASC : SortOrder.DESC;
//			
//			sourceBuilder.sort(strings[0], order);
//		}

//		sourceBuilder.from((searchParam.getPageNum() - 1) * searchParam.getPageSize());
//		sourceBuilder.size(searchParam.getPageSize());

//		if(StringUtils.isNoneEmpty(searchParam.getKeyword())) {
//			HighlightBuilder builder = new HighlightBuilder();
//			builder.field("fileTitle");
//			builder.preTags("<b style='color:red'>");
//			builder.postTags("</b>");
//			sourceBuilder.highlighter(builder);
//		}

		/**
		 * 聚合分析
		 */
		String dslstring = sourceBuilder.toString();

		System.out.println(dslstring);

		SearchRequest request = new SearchRequest(new String[] { EsConstant.FILE_INDEX }, sourceBuilder);
		return request;
	}

}
